﻿using System;
using System.Configuration;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using System.Collections.Generic;

namespace CLFramework.MSSqlExport
{
    class Program
    {
        static void Main(string[] args)
        {
            #region Startup

            Console.WriteLine("MSSqlExport Command Line Utility, Version 1.0");
            Console.WriteLine("Copyright (c) 2011 KXTX. All Rights reserved.");
            Console.WriteLine();
            Console.WriteLine("Gets and export database scripts.");
            Console.WriteLine();

            PublishingConfiguration config = PublishingConfiguration.GetConfig();

            if (args.Length == 0 && config == null)
            {
                Console.WriteLine("Required parameters:");
                Console.WriteLine("  /s:                IP of SQL Server.");
                Console.WriteLine("                      e.g. 192.168.4.99");
                Console.WriteLine("  /u:                Logon name of SQL Server.");
                Console.WriteLine("  /p:                Password of SQL Server.");
                Console.WriteLine("  /d:                Database name.");
                Console.WriteLine();
                Console.WriteLine("Optional parameters:");
                Console.WriteLine("  /schema:           Schema which need to export.");
                Console.WriteLine("                      e.g. dbo");
                Console.WriteLine("  /filename:         The patch and filename to store sql script.");
                Console.WriteLine("                      e.g. dbo.sql C:\\dbo.sql");
                Console.WriteLine("  /list               Displays a list with all settings.");
                Console.WriteLine();
                Console.ReadLine();
            }

            #endregion

            #region Retrive Parameters

            Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);

            foreach (string str in args)
            {
                if (!(str.StartsWith("/") || str.StartsWith("-")))
                {
                    Console.WriteLine("Invalid Parameter: " + str);
                    Console.WriteLine();
                    return;
                }
                int index = str.IndexOf(':');
                if (index == -1)
                {
                    dictionary.Add(str.Substring(1), "true");
                }
                else
                {
                    dictionary.Add(str.Substring(1, index - 1), str.Substring(index + 1));
                }
            }

            #endregion

            string connectionstring = string.Empty;
            Server server = null;
            try
            {

                if (ConfigurationManager.ConnectionStrings["SqlServer"] != null && ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString != string.Empty && config != null)
                {
                    connectionstring = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;
                }
                else
                {
                    connectionstring = string.Format("server={0};uid={1};pwd={2};database={3}", dictionary["s"], dictionary["u"], dictionary["p"], dictionary["d"]);
                    config = new PublishingConfiguration();
                    ScriptConfig sc = new ScriptConfig();
                    sc.Schema = dictionary.ContainsKey("schema") ? dictionary["schema"] : "dbo";
                    sc.Filename = dictionary.ContainsKey("filename") ? dictionary["filename"] : sc.Schema + ".sql";
                    sc.ScriptDrops = false;
                    sc.SchemaQualify = true;
                    sc.ServerVersion = MSSqlExport.ServerVersion.SqlServer2008;
                    sc.PublishType = PublishType.SchemaOnly;
                    sc.SchemaOnly = dictionary.ContainsKey("schemaOnly") ? Convert.ToBoolean(dictionary["schemaOnly"]) : true;

                    config.ScriptConfigs.Add(sc);
                }

                SqlConnection sqlConn = new SqlConnection(connectionstring);
                ServerConnection conn = new ServerConnection(sqlConn);
                server = new Server(conn);
                server.ConnectionContext.Connect();

                foreach (ScriptConfig sc in config.ScriptConfigs)
                {
                    try
                    {
                        ScriptingEngine engine = new ScriptingEngine(server, sc);
                        Database dataBase = server.Databases[dictionary["d"] ?? conn.DatabaseName];
                        engine.GenerateScript(dataBase, dataBase.Schemas[sc.Schema]);
                        if (!sc.SchemaOnly)
                            engine.GenerateData(dataBase, dataBase.Schemas[sc.Schema]);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
                Console.WriteLine("All done! Please enter any key to exit.");
                if (dictionary.Count>1)
                    return;
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.Read();
            }
            finally
            {
                if (server != null && server.ConnectionContext.IsOpen)
                    server.ConnectionContext.Disconnect();
            }

        }
    }
}
